#include "bin_otsu.h"

#include "histogram_equalization.h"
#include "../histogram.h"

BinarizationOtsu::BinarizationOtsu(PNM* img) :
    Transformation(img)
{
}

BinarizationOtsu::BinarizationOtsu(PNM* img, ImageViewer* iv) :
    Transformation(img, iv)
{
}

PNM* BinarizationOtsu::transform()
{
    int width = image->width();
    int height = image->height();

    PNM* newImage = new PNM(width, height, QImage::Format_Mono);

	HistogramEqualization* heq = new HistogramEqualization(image);
    heq->start();

	double bcv[256];

	auto histogram = image->getHistogram()->get(Histogram::LChannel); 

	int max = 0;
	int T= 0;

	for(int t = 0; t < 256; t++)
	{	
		int sum1 = 0;
		int sum2 = 0;

		for(int i = 0; i < t + 1; i++)
		{
			sum1 += histogram->value(i);
			sum2 += histogram->value(i) * i;
		}

		float w_b = 0;
		float u_b = 0;
		
		w_b = sum1 / std::pow(255, 2);
		
		if(sum1 != 0)
		{
			u_b = sum2 / sum1;
		}

		int sum3 = 0;
		int sum4 = 0;

		for(int i = t; i < 256; i++)
		{
			sum3 += histogram->value(i);
			sum4 += histogram->value(i) * i;
		}

		float w_f = 0;
		float u_f = 0;

		w_f = sum3 / std::pow(255, 2);
		
		if(sum3 != 0)
			u_f = sum4 / sum3;

		bcv[t] = w_b * w_f * std::pow(u_b - u_f, 2);
		if(bcv[t] > max) { max = bcv[t]; T = t ;}
	}



    if (image->format() == QImage::Format_Indexed8)
	{
		for (int i = 0; i < width; i++)
		{
			for (int j = 0; j < height; j++)
			{
				QRgb pixel = image->pixel(i,j);
				if(qGray(pixel) <= T) newImage->setPixel(i, j, 0);
				else newImage->setPixel(i, j, 1);
			}
		}
	}
	else {
		qDebug() << Q_FUNC_INFO << "Image should be gray scaled";
	}

    return newImage;
}

